package com.cheng.shiro;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cheng.common.utils.StringUtil;
import com.cheng.data.entity.PermInfoEntity;
import com.cheng.data.mapper.PermInfoMapper;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: ChengJW
 * @date: 2021/11/2 7:18
 * @version: 1.0
 * @description: shiro 配置文件
 */
@Configuration
public class ShiroConfig {

    @Autowired
    private PermInfoMapper permInfoMapper;

    /**
    * @author: ChengJW
    * @params: []
    * @return: com.cheng.shiro.CustomCreditMatcher
    * @date: 2021/11/2
    * @description: 注册 shiro 匹配器
    */
    @Bean
    public CustomCreditMatcher createCustomCreditMatcher(){
        return new CustomCreditMatcher();
    }

    /**
    * @author: ChengJW
    * @params: []
    * @return: com.cheng.shiro.CustomRealm
    * @date: 2021/11/2
    * @description: 注册 realm
    */
    @Bean
    public CustomRealm createCustomRealm(){
        CustomRealm customRealm = new CustomRealm();
        customRealm.setCredentialsMatcher(createCustomCreditMatcher());
        return customRealm;
    }

    /**
    * @author: ChengJW
    * @params: []
    * @return: org.apache.shiro.web.mgt.DefaultWebSecurityManager
    * @date: 2021/11/2
    * @description: 注册 securityManager 安全管理器
    */
    @Bean
    public DefaultWebSecurityManager createDefaultWebSecurityManager(){
        DefaultWebSecurityManager webSecurityManager = new DefaultWebSecurityManager();
        webSecurityManager.setRealm(createCustomRealm());
        return webSecurityManager;
    }

    /**
    * @author: ChengJW
    * @params: []
    * @return: org.apache.shiro.spring.web.ShiroFilterFactoryBean
    * @date: 2021/11/2
    * @description: 配置shiro框架的过滤链
    */
    @Bean
    public ShiroFilterFactoryBean createShiroFilterFactoryBean(){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        //配置安全管理器
        factoryBean.setSecurityManager(createDefaultWebSecurityManager());
        Map<String,String> filterMap = new LinkedHashMap<>();

        //配置 shiro 登录页面，不配置，则当用户未登录或登录超时之后，默认跳转至 springboot 根目录下的 login.jsp 页面
        factoryBean.setLoginUrl("/login");
        //添加无需验证的资源
        anonChain(filterMap);
        //添加菜单权限
        //权限控制只到菜单这一层，也就是说，页面上的增删改查功能，只需要登录身份认证就可以，不做具体的权限控制
        permsChain(filterMap);
        filterMap.put("/**","authc");
        factoryBean.setFilterChainDefinitionMap(filterMap);
        return factoryBean;
    }

    /**
    * @author: ChengJW
    * @params: [map]
    * @return: void
    * @date: 2022/1/4
    * @description: 添加无需验证的资源至过滤链
    */
    public void anonChain(Map<String,String> filterMap){
        //系统首页不设置权限
        filterMap.put("/login","anon");
        //登录url不设置权限
        filterMap.put("/UserLogin","anon");
        //生成验证码不设置权限
        filterMap.put("/showCheckCOde","anon");
        //获取游客访问信息不设置权限
        filterMap.put("/visitor","anon");
        //静态资源不设置权限
        filterMap.put("/images/**","anon");
        filterMap.put("/css/**","anon");
        filterMap.put("/js/**","anon");
        filterMap.put("/docs/**","anon");
        filterMap.put("/xlsx/**","anon");
        filterMap.put("/layui/**","anon");
    }

    /**
     * @author: ChengJW
     * @params: []
     * @return: java.util.List<com.cheng.data.entity.PermInfoEntity>
     * @date: 2022/1/4
     * @description: 添加菜单权限至过滤链表
     */
    public void permsChain(Map<String,String> filterMap){
        String prId = null;
        QueryWrapper<PermInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtil.isNotNull(prId),"pr_id",prId);
        List<PermInfoEntity> list = permInfoMapper.selectList(wrapper);
        if (list != null && list.size() > 0){
            for (PermInfoEntity entity : list){
                filterMap.put(entity.getPrUrl(),"perms[" + entity.getPrNm() + "]");
            }
        }
    }
}
